`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    11:01:07 03/30/2014 
// Design Name: 
// Module Name:    TOP 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module TOP(R0,R1,R2,R3,R4,R5,R6,R7,pc,cmp_flag,
				P1_Out, P1_Bullet, Alien_Pos, Alien_Status, Bonus_Out, Score, Shields_Out,
				status, //outputs for screen debugging use
				vid_line,aud_line,poll_line, //outputs to control other parts of the game
				clk,reset,resume_button,clk_key, data_key,Alien_Bullet);
output wire [15:0] R0,R1,R2,R3,R4,R5,R6,R7;

//output [21:0] O_Player1;
//output [10:0] O_Score;
//output [362:0] O_Line1;
//output [362:0] O_Line2;
//output [362:0] O_Line3;
//output [362:0] O_Line4;
//output [362:0] O_Line5;
//output [43:0] O_Shield;
//output [32:0] O_Player1_bullet;
//output [32:0] O_RS_bullet;
//output [32:0] O_PS_bullet;
//output [32:0] O_SS_bullet;
//output [21:0] O_Bonus;

output wire [12:0] P1_Out;
output wire [21:0] Alien_Pos;
output wire [21:0] Alien_Status;
output wire [22:0] P1_Bullet;
output wire [22:0] Alien_Bullet;
output wire [11:0] Bonus_Out;
output wire [10:0] Score;
output wire [7:0] Shields_Out;

output wire [11:0] pc;
output wire vid_line, poll_line;
output wire [3:0] aud_line;
output wire [1:0] cmp_flag;
input clk, clk_key, data_key, reset, resume_button;

//////////////////////
// ROM Lines
//////////////////////
wire [18:0] instruction;

//////////////////////
// from instruction
//////////////////////
wire [4:0] opcode;
wire [2:0] Rn,Ra,Rb;
wire [7:0] Imm;
wire [11:0] Jump_target;

assign opcode = instruction[18:14];
assign Rn = instruction[13:11];
assign Ra = instruction[10:8];
assign Rb = instruction[2:0];
assign Imm = instruction[7:0];
assign Jump_target = instruction[11:0];

//////////////////////
// Control Unit lines
//////////////////////
wire Jump,MemRead,MemToReg,MemWrite,ALU_Src,RegWrite;

//////////////////////
// outputs from regfile
//////////////////////
wire [15:0] reg_2;

//////////////////////
// inputs to ALU
//////////////////////
wire [15:0] Arg_1,Arg_2;
assign Arg_2 = (ALU_Src) ? {8'd0,Imm} : reg_2;

//////////////////////
//ouputs from ALU
//////////////////////
wire [15:0] ALU_Out;
wire halt_out, branch_out;

//////////////////////
// write back
//////////////////////
wire [15:0] data_out;
wire [15:0]write_back;
assign write_back = (MemToReg) ? data_out : ALU_Out;

//////////////////////
// halt control
//////////////////////
reg halt = 1'b0;
reg last_resume = 1'b0;
wire resume,resume_line;

debouncer D0(resume,resume_button,clk);

always @(posedge clk)
	if(reset)
		last_resume = 1'b0;
	else if(resume == 1)
		last_resume = 1'b1;
	else
		last_resume = 1'b0;
		
assign resume_line = resume && ~last_resume;

always @(halt_out or resume_line)
	halt = halt_out && ~resume_line;
//
////////
// defining the GO signal
////////
//reg Go = 1'b0; //will flip everytime the ALU changes a thing
//
//always @(ALU_Out or vid_line or aud_line or poll_line or branch_out)
//	Go <= ~Go;

////////
//submodules
////////	
output wire [5:0] status;



PC_Control P0(pc,Jump,branch_out,Jump_target,halt,clk,reset);// pc 

ROM RM(clk,instruction,pc);//

reg_file RF(Arg_1,reg_2,R0,R1,R2,R3,R4,R5,R6,R7,Rn,Ra,Rb,write_back,RegWrite,clk,reset);

ALU A0(ALU_Out,halt_out,branch_out,vid_line,aud_line,poll_line,cmp_flag,Arg_1,Arg_2,opcode,reset,clk);//

Control_Unit C0(Jump,MemRead,MemToReg,MemWrite,ALU_Src,RegWrite,opcode);//

RAM RA(data_out,
		 P1_Out, P1_Bullet, Alien_Pos, Alien_Status, Bonus_Out, Score, Shields_Out,
		 status,poll_line,vid_line,ALU_Out,reg_2,MemRead,MemWrite,clk, Alien_Bullet);//

//Keyboard module,  feeds input to the RAM module

user_control UC(clk, clk_key, data_key, reset, status); //status == [right, left, bullet]

endmodule
